Handling Events
React elementsのイベントハンドリングはDOMのイベントハンドリングに似ている
ここではそのシンタックスの違いについて
ReactイベントはcamelCaseで書く
イベントハンドラに文字列ではなく関数を渡す
code:JavaScript
/* HTMLでの書き方 */
<button onclick="activateLasers()">
Activate Lasers
</button>
/* React(JSX)での書き方 */
<button onClick={activateLasers}>
Activate Lasers
</button>
preventDefaultする際にfalseを返すだけではダメで、明示的にe.preventDefault()する必要がある
code:JavaScript
/* HTML */
<a href="#" onclick="console.log('The link was clicked.'); return false">
Click me
</a>
/* React(JSX) */
function ActionLink() {
function handleClick(e) {
e.preventDefault();
console.log('The link was clicked.');
}
return (
<a href="#" onClick={handleClick}>
Click me
</a>
);
}
ここでhandleClick関数に渡されるeは、各ブラウザで互換性のあるW3Cで定義されたイベントをReactが定義している
基本的にaddEventListenerを使う必要はない
レンダリング時にリスナーを提供するだけでよい
リスナー登録時の注意点としてthisの使い方がある
これはReactに限った話ではなくJS全般的な話で、クラスのメソッド内ではthisでクラス内を参照できず、関数実行時にundefinedとなっている
code:JavaScript
// やり方1
// コンストラクタでフィールドに格納
this.handleClick = this.handleClick.bind(this); // あらかじめthisをバインドしておく必要がある
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
// やり方2
<button onClick={this.handleClick.bind(this)}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
// やり方3
// public class fields
handleClick = () => {
console.log('this is:', this); // アロー関数なのでthisが固定化されているという理解
}
<button onClick={this.handleClick}>
Click me
</button>
// やり方4
handleClick() {
console.log('this is:', this);
}
<button onClick={(e) => this.handleClick(e)}> // ここでアロー関数使っても同様の効果
Click me
</button>
「やり方4」には問題もある
renderメソッドが呼ばれるたびに別のコールバックが生成される
たいていのケースではこれで問題ない
このコールバックがpropsとして子コンポーネントに渡される場合は、余計な再レンダリングが行われることになるかも
React的な推奨は「やり方1」
「やり方2」は「やり方4」と同じになるらしい
つぎの「Passing Arguments to Event Handlers」の例参照
Passing Arguments to Event Handlers
code:JavaScript
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
Reactイベントをあらわす引数eの渡し方が異なる
アロー関数は必ず渡す
bindの場合は渡す必要なし(最後の引数に自動的に渡される?)